/* 泛型函数 */
function returnType<T>(arg: T): T {
    return arg
}

returnType<Number>(123)
returnType<number | string>('123')
returnType<any>('123')




/* 交换【两元素元组】两个元素的位置 */
function swap<T, U>(tuple: [T, U]): [U, T] {
    return [tuple[1], tuple[0]]
}

swap<string, number>(["张三", 60])
swap<string, number>([60, '张三'])


/* 泛型接口 */
interface ReturnItemFn<T> {
    (para: T): T
}
const returnItem: ReturnItemFn<number> = para => para

interface Person<U> {
    name: string,

    // 最爱（写什么类型都行）
    favorite: U,
}

let p1: Person<string>

p1 = {
    name: '张三',
    favorite: '豆腐脑儿'
}
p1 = {
    name: '张三',
    favorite: { name: '豆腐脑儿' }
}
const p2: Person<object> = {
    name: '张三',
    favorite: { name: '豆腐脑儿' }
}



/* 泛型类  */
/* 定义队列类型（先入先出） */
class Queue<T> {
    arr: T[]

    constructor(arr: T[]) {
        this.arr = arr
    }

    push(item: T) {
        this.arr.push(item)
    }

    pop(): T | undefined {
        return this.arr.shift()
    }
}


class TupleQue<T, U> {
    arr: [T, U][]

    constructor(arr: Array<[T, U]>) {
        this.arr = arr
    }

    push(item: [T, U]) {
        this.arr.push(item)
    }

    pop(): [T, U] | undefined {
        return this.arr.shift()
    }
}

/* [  [姓名,ID],[姓名,ID],[姓名,ID]...  ] */
const data = new TupleQue<string, number>([])
data.push(["张三", 123])
// data.push(["张三",'123'])
data.pop()